package edu.mtu.citizenscience.cs.sdk;

import java.io.IOException;

import android.util.Log;

import com.androidquery.callback.AjaxCallback;
import com.androidquery.callback.AjaxStatus;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import edu.mtu.citizenscience.cs.sdk.json.Response;
/**
 * @author Corbin Uselton <corbinu@cwuselto@mtu.edu>
 * @copyright (c) 2012 MichiganTech <http://www.mtu.edu>
 * @since 1.0
 * 
 * Callback for requests to the server via AQuery
 * Converts the response JSON String into a Response
 * object and then passes the response in success or error
 * to the Response handler for this specific request
 */
public class RequestCallback extends AjaxCallback<String> {
	// Handles the response to this specific request
	ResponseHandler<?> handler;
	
	/**
	 * Create the request callback with a Response Handler
	 * 
	 * @param   handler - ResponseHandler<?> - Handles the specific requests response
	 * @return	void
	 */
	RequestCallback(ResponseHandler<?> handler)
	{
		// save the handler for a response
		this.handler = handler;
	}

	/**
	 * Called when AQuery recives a response from the server
	 * 
	 * @param   url - String - the URL of the request
	 * @param   json - String - the json String returned from the server
	 * @param   status - AjaxStatus - the status of the response
	 * @return	void
	 */
    @SuppressWarnings("unchecked")
	@Override
    public void callback(String url, String json, AjaxStatus status) 
    {
    	try 
    	{
    		// check if nothing was returned
    		if (json == null)
    		{
    			// if not then tell handler there was no response
    			this.handler.noResponse();
    		}
    		else
    		{
    			Log.d("SDK", "New response:" + json);
    			// Read the JSON String into a Response Object
				@SuppressWarnings("rawtypes")
				Response response = new ObjectMapper().readValue(json, Response.class);
				// Set the type of the response payload for this request from the handler's expected payload type
	    		response.setPlayloadType(handler.getPlayloadType());
	    		// check that the response has received a payload
				if (response.havePayload())
				{
					// pass the response on to the handler
					this.handler.response(response);
				}
				else
				{
					// since no payload pass the error onto the handler
					this.handler.error(response);
				}
    		}
		} 
    	catch (JsonParseException e) 
    	{
    		// when the JSON String is not formatted correctly pass the exception onto the handler
    		this.handler.exception(e);
		} 
    	catch (JsonMappingException e) 
    	{
    		// when the Response Object is not formatted correctly pass the exception onto the handler
    		this.handler.exception(e);
		} 
    	catch (IOException e) 
    	{
			e.printStackTrace();
		}
    }
}
